iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0

ARIMA模型

ARIMA模型是一種時間序列分析模型,想要了解它就必須先聽聞過另外三種知名的時間序列分析模型

  • 自回歸模型-AR模型

  • 移動平均模型-MA模型

  • 自回歸滑動平均模型-ARMA模型
    而ARMA模型是將上面兩種時間序列分析模型,AR模型、MA模型整合在一起的產物,而ARIMA則是以ARMA做優化的產品,時間序列分析模型的目的大多數都是要拿以現有的數據來預測未來,而這些模型都有自己的特色,下面來一一簡單介紹一下

AR模型

常寫為AR(p)
公式為:

Yt = α+β1Yt-1+β2Yt-2+…+βpYt-p+ɛt

公式這裡就不細說了,要多複雜的解釋網路上那裡都有,這裡就簡單說明
AR模型就是以前期的資料來預測本期的資料,而且越接近本期的資料,對預測結果的影響力就越大
如果我們想預測五分鐘後的氣溫,我想大多數都認同30分鐘前的資料比3天前的資料更具有參考價值這個觀點吧,而AR模型正是把這個觀點以數學的方式呈現出來,而且AR模型是以過去p筆資料的線性組合來預測的,因此才會寫成AR(p),p是我們要挑選的過去資料的筆數,然而現實生活中很少有自然現象會真的以線性的方式出現,因此AR模型為了貼近真實生活中的數據,會在加上一個隨機變數,因此我們可以簡單的將公式解讀為

預測值 = 常數 + [ ( 前1期資料的影響力 * 前1期資料的數值 ) + ... + ( 前p期資料的影響力 * 前p期資料的數值 ) ] + 隨機變數

MA模型

常寫為MA(q)
公式為:

Yt = α+ɛt+Φ1ɛt-1+Φ2ɛt-2+…+Φqɛt-q

這稱為移動平均模型,q是前面幾期的筆數,我們簡單的將公式解讀為

預測值 = 平均數 + [ ( Φ1 * ɛt-1 ) + ... + ( Φq * ɛt-q ) ] + 隨機變數

其中最重要的是 ( Φ1 * ɛt-1 ) ~ ( Φq * ɛt-q ) 這幾項的累加,我們一一分開來看
Φ是介於-1~1之間,可以想像為影響力的大小
ɛ是殘差值
我們簡單的將殘差值的公式解讀為

殘差值 = 隨機變數 + [ ( 前1期資料的影響力 * 前1期資料的數值 ) + ... + ( 前p期資料的影響力 * 前p期資料的數值 ) ]

ARMA模型

公式為

Xt = c + εt + β1Yt-1+β2Yt-2+…+βpYt-p + Φ1ɛt-1+Φ2ɛt-2+…+Φqɛt-q

仔細看公式,斜體的部份正好就是 AR及MA模型的一部分,所以寫法為ARMA(p,q)

ARIMA模型

上述三種模型雖有其強大之處,也有相應的缺陷,就是這三種模型只能處理穩定的資料,而ARIMA模型就是為了解決這問題而誕生的,它自帶了第三個參數,差分項,因此能將非穩定的資料處理成穩定的資料,常寫成ARIMA(p,d,q),其中d就是為了使資料平穩所作的差分次數,我們直接往下實做,我們就以昨天補值的資料做範例

首先要先對資料做平穩化處理,這裡我們直接暴力解決,直接讓它幫我們算出推薦的差分次數,差分後要如何檢查穩不穩定呢?這時候就要使用穩定性檢驗法,其中最知名的就是ADF檢驗法,因此我們要在ndiffs()裡面加上test="adf"參數,意思就是,通過ADF檢驗法的差分次數,就是我們要的答案

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt 
from pmdarima.arima import ndiffs


if __name__ == "__main__":
    data = pd.read_csv("./OK.csv")

    # 有些插值法是時間序列專用,所以最好先將索引轉成時間
    data["time"] = pd.to_datetime(data["time"])
    data = data.set_index("time")

    # 算出推薦的差分次數
    d =  ndiffs(data["time_imputed"],  test="adf")
    print(d) # 1

接著我們要來挑選p參數,這是要透過偏自相關函數圖PACF圖來幫助我們選擇,簡單來說PACF圖可以讓我們看出,究竟多久遠以前的資料,對於我們的預測還具有影響力,畢竟AR(p)模型中就是不斷的強調過去資料對現在的影響力嘛

我們來簡單的說明一下這張圖,每一根柱子都表示過去的一筆資料,我們前兩跟柱子,非常接近1,所以表示影響力非常大,而第三跟柱子也很大根,可是卻是接近-1的,表示前第三筆資料的增加將會造成預測數值的縮小,而低於陰影的筆數則代表影響力過低,沒用,因此這裡p值選擇7

最後我們要來挑選q參數,這要透過自相關函數圖ACF圖來幫助我們選擇,用法跟PACF圖差不多

不用說了,直接選35吧

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt 
from pmdarima.arima import ndiffs
from statsmodels.graphics.tsaplots import plot_pacf, plot_acf


if __name__ == "__main__":
    data = pd.read_csv("./OK.csv")

    # 有些插值法是時間序列專用,所以最好先將索引轉成時間
    data["time"] = pd.to_datetime(data["time"])
    data = data.set_index("time")

    # 算出推薦的差分次數
    d =  ndiffs(data["time_imputed"],  test="adf")
    print(d) # 1

    #  觀察PACF圖,參數是差分之後的資料
    plot_pacf(data["time_imputed"].diff(1))
    plt.show()

    #  觀察ACF圖,參數是差分之後的資料
    plot_acf(data["time_imputed"].diff(1))
    plt.show()

接著直接來做ARIMA模型預測吧,我們用資料的前90%來預測後面10%

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt 
from pmdarima.arima import ndiffs
from statsmodels.graphics.tsaplots import plot_pacf, plot_acf
from statsmodels.tsa.arima_model import ARIMA


if __name__ == "__main__":
    data = pd.read_csv("./OK.csv")

    # 有些插值法是時間序列專用,所以最好先將索引轉成時間
    data["time"] = pd.to_datetime(data["time"])
    data = data.set_index("time")

    # 算出推薦的差分次數
    d =  ndiffs(data["time_imputed"],  test="adf")
    print(d) # 1

    # #  觀察PACF圖,參數是差分之後的資料
    # plot_pacf(data["time_imputed"].diff(1))
    # plt.show()

    # #  觀察ACF圖,參數是差分之後的資料
    # plot_acf(data["time_imputed"].diff(1))
    # plt.show()
    
    # 過去資料
    data_set = data["time_imputed"][:int(0.9*data.shape[0])].copy()
    # 正確答案
    target = data["time_imputed"][int(0.9*data.shape[0]):].copy()
    # 建立模型
    model = ARIMA(data_set,order=(7,1,35)).fit(disp=0)
    # 模型預測
    predict = model.forecast(steps=int(0.9*data.shape[0]))

上一篇
#14 補值教學
下一篇
#16 數據上的各種距離(1)
系列文
終極大數據地獄24
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言